﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MethodWorx.CMS.Providers;
using MethodWorx.CMS.TemplateParser.Installer;
using System.Web.Mvc;
using MethodWorx.Core.DomainModel;
using MethodWorx.CMS.Services;

namespace MethodWorx.CMS.UI.Areas.Dashboard.Models
{
    public class TemplateInstallModel
    {
        private InstallerParser parser;
        private ContentService content;

        public TemplateInstallModel(InstallerParser parser, int currentStep, ContentService content, bool macro) 
        {
            this.Steps = parser.WizardSteps;
            this.parser = parser;
            this.CurrentStepIndex = currentStep;
            this.TotalSteps = parser.WizardSteps.Length;
            this.Macro = macro;
            this.content = content;
        }

        public bool Macro { get; private set; }

        public WizardStep[] Steps
        {
            get; private set;
        }

        public string Complete { get; private set; }

        public WizardStep CurrentStep
        {
            get { return this.Steps[this.CurrentStepIndex]; }
        }

        public SelectList GetPagesByTemplateSelectList(string template)
        {
            var templates = this.content.GetPagesByTemplate(template);

            return new SelectList(templates, "Id", "Name");
        }

        public int CurrentStepIndex { get; set; }
        public int TotalSteps { get; private set;  }
        public Dictionary<string, string> Values { get; private set; }

        public bool IsLastStep
        {
            get { return CurrentStepIndex == TotalSteps - 1; }
        }

        internal void UpdateFromFormCollection(FormCollection form, ModelStateDictionary msd)
        {
            foreach(var key in form.Keys)
            {
                if(key.ToString().StartsWith("prompts."))
                {
                    //
                    //  ok, this is it
                    var promptName = key.ToString().Substring(8);
                    bool set = false;
                    foreach (var step in this.Steps)
                    {
                        foreach (var prompt in step.Prompts)
                        {
                            if (prompt.Variable == promptName)
                            {
                                //  put the value in here 
                                prompt.Value = (string)form[key.ToString()];
                                if (string.IsNullOrEmpty(prompt.Value))
                                    msd.AddModelError(key.ToString(), "This field is required");

                                set = true;
                                break;
                            }
                        }

                        if (set)
                            break;
                    }
                }
            }
        }

        internal void NextStep()
        {
            this.CurrentStepIndex++;
        }

        internal void Install(ICmsDataProvider cmsDataProvider, ModelStateDictionary msd)
        {
            //
            //  ok, time for us to install this model
            try
            {
                using(var uow = cmsDataProvider.GetUnitOfWorkFactory().Begin())
                {
                    this.parser.GetWorkflowExecutionEngine(cmsDataProvider).Execute();
                    uow.Commit();
                }

                this.Complete = this.parser.Complete;
            }
            catch (BusinessRuleException bre)
            {
                this.InstallationError = bre.Message;
                bre.AddToModelState(msd);
            }
            catch (Exception ex)
            {
                this.InstallationError = ex.Message;
            }
        }

        public string InstallationError { get; private set; }
    }
}